package com.mixsmart.exception;

import com.mixsmart.utils.StringUtils;

/**
 * 运行时的wrapped异常；异常包装类；便于获取原始异常
 * @author 乌草坡 2024-01-10
 * @since 2.6.5
 */
public class WrappedRuntimeException extends RuntimeException {

    private final Exception exception;

    private final Throwable throwable;

    public WrappedRuntimeException(Exception exception) {
        super(exception.getCause());
        this.exception = exception;
        this.throwable = exception;
    }

    public WrappedRuntimeException(Throwable throwable) {
        super(throwable.getCause());
        this.exception = null;
        this.throwable = throwable;
    }

    public Exception getException() {
        return exception;
    }

    public Throwable getThrowable() {
        return throwable;
    }

    public static WrappedRuntimeException wrap(Exception e) {
        if (e instanceof WrappedRuntimeException wrappedException) {
            return wrappedException;
        }
        return new WrappedRuntimeException(e);
    }

    public static WrappedRuntimeException wrap(Throwable e) {
        if (e instanceof WrappedRuntimeException wrappedException) {
            return wrappedException;
        }
        return new WrappedRuntimeException(e);
    }

    public static Throwable unwrap(Throwable e) {
        if (e instanceof WrappedRuntimeException wrappedException) {
            if(null == wrappedException.getException()) {
                return wrappedException.getThrowable();
            } else {
                return wrappedException.getException();
            }
        }
        return e;
    }

    public static Exception unwrap(Exception e) {
        if (e instanceof WrappedRuntimeException wrappedException) {
            return wrappedException.getException();
        }
        return e;
    }

    @Override
    public String getMessage() {
        return (null == exception) ? throwable.getMessage() : exception.getMessage();
    }

    public String getDetailMessage() {
        if(null == exception) {
            return StringUtils.getThrowableStackTrace(throwable);
        }
        return StringUtils.getExceptionStackTrace(exception);
    }

    @Override
    public String getLocalizedMessage() {
        if(null == exception) {
            return throwable.getLocalizedMessage();
        }
        return exception.getLocalizedMessage();
    }
}
